SPECIAL_ORTHO_GROUP

Overview

The SPECIAL_ORTHO_GROUP function generates random rotation matrices from the special orthogonal group SO(N), which is the group of all orthogonal N \times N matrices with determinant +1. These matrices represent proper rotations in N-dimensional Euclidean space, preserving both distances and orientation.

This implementation uses the scipy.stats.special_ortho_group distribution from SciPy. The function draws random samples from the Haar distribution, which is the unique uniform distribution on SO(N). The Haar measure, named after mathematician Alfréd Haar, provides a mathematically rigorous way to sample “uniformly at random” from continuous groups like SO(N). For more mathematical background, see the Wikipedia article on orthogonal groups.

An orthogonal matrix Q satisfies the property:

Q Q^T = Q^T Q = I

where I is the identity matrix and Q^T is the transpose of Q. For SO(N) specifically, the additional constraint \det(Q) = +1 ensures the transformation is a pure rotation without reflection.

The algorithm generates a Haar-distributed orthogonal matrix using scipy.stats.ortho_group, then adjusts the result to guarantee the determinant is +1. For 3D rotations specifically, SciPy also provides scipy.spatial.transform.Rotation.random as an alternative.

Random rotation matrices from SO(N) have applications in:

  • 3D graphics and robotics: Generating random orientations for objects or sensors
  • Monte Carlo simulations: Sampling over rotation spaces
  • Statistical physics: Modeling spin systems and lattice gauge theories
  • Machine learning: Random projections and data augmentation with rotational transformations

This example function is provided as-is without any representation of accuracy.

Excel Usage

=SPECIAL_ORTHO_GROUP(dim, size)
  • dim (int, required): Dimension of the square matrix (must be >= 2).
  • size (int, optional, default: null): Number of matrices to generate (must be >= 1). If omitted, returns a single matrix.

Returns (list[list]): 2D orthogonal matrix, or error message string.

Examples

Example 1: Single 3x3 orthogonal matrix

Inputs:

dim
3

Excel formula:

=SPECIAL_ORTHO_GROUP(3)

Expected output:

"non-error"

Example 2: Two 3x3 orthogonal matrices stacked

Inputs:

dim size
3 2

Excel formula:

=SPECIAL_ORTHO_GROUP(3, 2)

Expected output:

"non-error"

Example 3: Single 4x4 orthogonal matrix

Inputs:

dim
4

Excel formula:

=SPECIAL_ORTHO_GROUP(4)

Expected output:

"non-error"

Example 4: Three 4x4 orthogonal matrices stacked

Inputs:

dim size
4 3

Excel formula:

=SPECIAL_ORTHO_GROUP(4, 3)

Expected output:

"non-error"

Python Code

import numpy as np
from scipy.stats import special_ortho_group as scipy_special_ortho_group

def special_ortho_group(dim, size=None):
    """
    Draws random samples from the special orthogonal group SO(N), returning orthogonal matrices with determinant +1.

    See: https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.special_ortho_group.html

    This example function is provided as-is without any representation of accuracy.

    Args:
        dim (int): Dimension of the square matrix (must be >= 2).
        size (int, optional): Number of matrices to generate (must be >= 1). If omitted, returns a single matrix. Default is None.

    Returns:
        list[list]: 2D orthogonal matrix, or error message string.
    """
    def to_2d_list(arr):
        """Convert numpy arrays to 2D lists."""
        arr = np.asarray(arr)
        if arr.ndim == 2:
            return arr.tolist()
        elif arr.ndim == 3:
            # Multiple matrices: flatten into a single 2D list
            return [row for mat in arr for row in mat.tolist()]
        else:
            return "Invalid output shape from scipy.special_ortho_group."

    def valid_matrix(matrix):
        """Check for invalid values in a 2D matrix."""
        for row in matrix:
            for val in row:
                if not isinstance(val, (int, float)):
                    return False
                if val != val or val in (float('inf'), float('-inf')):
                    return False
        return True

    # Validate dim - accept float if it represents an integer
    if isinstance(dim, float) and dim.is_integer():
        dim = int(dim)
    if not isinstance(dim, int) or dim < 2:
        return "Invalid input: dim must be an integer >= 2."

    # Validate size - accept float if it represents an integer
    if size is not None:
        if isinstance(size, float) and size.is_integer():
            size = int(size)
        if not isinstance(size, int) or size < 1:
            return "Invalid input: size must be an integer >= 1 or None."

    try:
        # Draw samples, only pass size if not None
        if size is None:
            result = scipy_special_ortho_group.rvs(dim)
        else:
            result = scipy_special_ortho_group.rvs(dim, size=size)
    except Exception as e:
        return f"scipy.special_ortho_group error: {e}"

    out = to_2d_list(result)

    if isinstance(out, list) and all(isinstance(row, list) for row in out):
        if not valid_matrix(out):
            return "Invalid output: matrix contains non-numeric or special values."
        return out

    return out

Online Calculator